#!/bin/bash

# Linux系统硬件测试脚本
# 作者: 1
# 功能: 全面检测和测试Linux系统硬件组件

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 创建日志文件
LOG_FILE="/tmp/hardware_test_$(date +%Y%m%d_%H%M%S).log"
exec 1> >(tee -a "$LOG_FILE")
exec 2> >(tee -a "$LOG_FILE" >&2)

# 打印带颜色的消息
print_message() {
    local color=$1
    local message=$2
    echo -e "${color}[$(date '+%Y-%m-%d %H:%M:%S')] $message${NC}"
}

# 检查命令是否存在
command_exists() {
    command -v "$1" >/dev/null 2>&1
}

# 安装必要的工具
install_tools() {
    print_message $BLUE "检查并安装必要的测试工具..."
    
    # 检查包管理器
    if command_exists apt; then
        PKG_MANAGER="apt"
        PKG_INSTALL="apt install -y"
    elif command_exists yum; then
        PKG_MANAGER="yum"
        PKG_INSTALL="yum install -y"
    elif command_exists dnf; then
        PKG_MANAGER="dnf"
        PKG_INSTALL="dnf install -y"
    else
        print_message $RED "未找到支持的包管理器"
        return 1
    fi
    
    # 需要的工具列表
    tools=("stress" "hdparm" "smartctl" "lscpu" "lsblk" "lsusb" "lspci" "dmidecode" "memtester" "iperf3")
    
    for tool in "${tools[@]}"; do
        if ! command_exists $tool; then
            print_message $YELLOW "正在安装 $tool..."
            case $tool in
                "stress")
                    sudo $PKG_INSTALL stress >/dev/null 2>&1
                    ;;
                "hdparm")
                    sudo $PKG_INSTALL hdparm >/dev/null 2>&1
                    ;;
                "smartctl")
                    sudo $PKG_INSTALL smartmontools >/dev/null 2>&1
                    ;;
                "memtester")
                    sudo $PKG_INSTALL memtester >/dev/null 2>&1
                    ;;
                "iperf3")
                    sudo $PKG_INSTALL iperf3 >/dev/null 2>&1
                    ;;
                *)
                    sudo $PKG_INSTALL $tool >/dev/null 2>&1
                    ;;
            esac
        fi
    done
}

# 系统基本信息
system_info() {
    print_message $BLUE "==================== 系统基本信息 ===================="
    
    echo "主机名: $(hostname)"
    echo "内核版本: $(uname -r)"
    echo "系统版本: $(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2)"
    echo "系统架构: $(uname -m)"
    echo "启动时间: $(uptime -s)"
    echo "运行时间: $(uptime -p)"
    echo "当前用户: $(whoami)"
    echo "系统负载: $(uptime | awk -F'load average:' '{print $2}')"
    echo
}

# CPU信息和测试
cpu_test() {
    print_message $BLUE "==================== CPU测试 ===================="
    
    # CPU基本信息
    echo "CPU信息:"
    lscpu | head -20
    echo
    
    # CPU核心数
    cores=$(nproc)
    echo "CPU核心数: $cores"
    
    # CPU频率
    if [ -f /proc/cpuinfo ]; then
        echo "CPU最大频率: $(cat /proc/cpuinfo | grep "cpu MHz" | head -1 | awk '{print $4}') MHz"
    fi
    
    # CPU温度（如果可用）
    if [ -d /sys/class/thermal ]; then
        echo "CPU温度:"
        for thermal in /sys/class/thermal/thermal_zone*/temp; do
            if [ -f "$thermal" ]; then
                temp=$(cat "$thermal")
                temp_c=$((temp/1000))
                echo "  温度传感器: ${temp_c}°C"
            fi
        done
    fi
    
    # CPU压力测试
    print_message $YELLOW "开始CPU压力测试（30秒）..."
    if command_exists stress; then
        timeout 30 stress --cpu $cores --quiet &
        stress_pid=$!
        
        # 监控CPU使用率
        for i in {1..6}; do
            cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
            echo "第${i}次检测 - CPU使用率: ${cpu_usage}%"
            sleep 5
        done
        
        # 等待压力测试完成
        wait $stress_pid 2>/dev/null
        print_message $GREEN "CPU压力测试完成"
    else
        print_message $RED "stress命令未找到，跳过CPU压力测试"
    fi
    echo
}

# 内存信息和测试
memory_test() {
    print_message $BLUE "==================== 内存测试 ===================="
    
    # 内存基本信息
    echo "内存信息:"
    free -h
    echo
    
    # 详细内存信息
    if command_exists dmidecode; then
        echo "内存条详细信息:"
        sudo dmidecode -t memory | grep -E "(Size|Speed|Type|Manufacturer)" | grep -v "No Module Installed"
        echo
    fi
    
    # 内存测试
    total_mem=$(free -m | awk 'NR==2{print $2}')
    test_mem=$((total_mem / 10))  # 测试10%的内存
    
    if [ $test_mem -lt 100 ]; then
        test_mem=100
    fi
    
    print_message $YELLOW "开始内存测试（测试${test_mem}MB内存）..."
    if command_exists memtester; then
        timeout 60 memtester ${test_mem}M 1 2>/dev/null
        if [ $? -eq 0 ]; then
            print_message $GREEN "内存测试通过"
        else
            print_message $RED "内存测试可能存在问题"
        fi
    else
        print_message $RED "memtester命令未找到，跳过内存测试"
    fi
    echo
}

# 硬盘信息和测试
disk_test() {
    print_message $BLUE "==================== 硬盘测试 ===================="
    
    # 硬盘基本信息
    echo "硬盘信息:"
    lsblk -d -o NAME,SIZE,MODEL,SERIAL
    echo
    
    # 磁盘使用情况
    echo "磁盘使用情况:"
    df -h
    echo
    
    # 硬盘SMART信息
    if command_exists smartctl; then
        echo "硬盘健康状态:"
        for disk in $(lsblk -d -n -o NAME | grep -E '^sd|^nvme'); do
            echo "检查 /dev/$disk:"
            smart_status=$(sudo smartctl -H /dev/$disk 2>/dev/null | grep "SMART overall-health" | awk '{print $6}')
            if [ "$smart_status" = "PASSED" ]; then
                print_message $GREEN "  /dev/$disk: 健康状态良好"
            elif [ -n "$smart_status" ]; then
                print_message $RED "  /dev/$disk: 健康状态异常"
            else
                echo "  /dev/$disk: 无法获取SMART信息"
            fi
        done
        echo
    fi
    
    # 硬盘读写速度测试
    print_message $YELLOW "开始硬盘读写速度测试..."
    
    # 选择根分区进行测试
    root_disk=$(df / | tail -1 | awk '{print $1}')
    
    # 写入测试
    echo "硬盘写入速度测试:"
    write_speed=$(dd if=/dev/zero of=/tmp/test_write bs=1024M count=1024 2>&1 | grep copied | awk '{print $(NF-1) " " $NF}')
    echo "写入速度: $write_speed"
    
    # 读取测试
    echo "硬盘读取速度测试:"
    read_speed=$(dd if=/tmp/test_write of=/dev/null bs=1024M 2>&1 | grep copied | awk '{print $(NF-1) " " $NF}')
    echo "读取速度: $read_speed"
    
    # 清理测试文件
    rm -f /tmp/test_write
    
    # 如果有hdparm，测试硬盘性能
    if command_exists hdparm; then
        for disk in $(lsblk -d -n -o NAME | grep -E '^sd' | head -1); do
            echo "硬盘 /dev/$disk 缓存读取速度:"
            sudo hdparm -t /dev/$disk | grep "Timing"
            echo "硬盘 /dev/$disk 直接读取速度:"
            sudo hdparm -T /dev/$disk | grep "Timing"
        done
    fi
    echo
}

# 网络测试
network_test() {
    print_message $BLUE "==================== 网络测试 ===================="
    
    # 网络接口信息
    echo "网络接口信息:"
    ip addr show | grep -E "(inet|ether)" | head -10
    echo
    
    # 网络连通性测试
    echo "网络连通性测试:"
    ping -c 3 8.8.8.8 > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        print_message $GREEN "外网连通性: 正常"
    else
        print_message $RED "外网连通性: 异常"
    fi
    
    ping -c 3 baidu.com > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        print_message $GREEN "DNS解析: 正常"
    else
        print_message $RED "DNS解析: 异常"
    fi
    
    # 网络速度测试（简单版）
    echo
    echo "网络延迟测试:"
    ping -c 5 8.8.8.8 | tail -1
    echo
}

# USB设备测试
usb_test() {
    print_message $BLUE "==================== USB设备测试 ===================="
    
    if command_exists lsusb; then
        echo "USB设备列表:"
        lsusb
        echo
        
        echo "USB设备详细信息:"
        lsusb -t
        echo
    else
        print_message $RED "lsusb命令未找到"
    fi
}

# PCI设备测试
pci_test() {
    print_message $BLUE "==================== PCI设备测试 ===================="
    
    if command_exists lspci; then
        echo "PCI设备列表:"
        lspci
        echo
        
        echo "显卡信息:"
        lspci | grep -i vga
        lspci | grep -i nvidia
        echo
        
        echo "声卡信息:"
        lspci | grep -i audio
        echo
        
        echo "网卡信息:"
        lspci | grep -i network
        lspci | grep -i ethernet
        echo
    else
        print_message $RED "lspci命令未找到"
    fi
}

# 传感器信息
sensor_test() {
    print_message $BLUE "==================== 传感器信息 ===================="
    
    if command_exists sensors; then
        echo "传感器读数:"
        sensors
        echo
    else
        print_message $YELLOW "sensors命令未找到，尝试读取系统温度信息..."
        
        # 尝试读取温度信息
        if [ -d /sys/class/thermal ]; then
            echo "系统温度信息:"
            for thermal in /sys/class/thermal/thermal_zone*/temp; do
                if [ -f "$thermal" ]; then
                    temp=$(cat "$thermal")
                    temp_c=$((temp/1000))
                    zone=$(basename $(dirname "$thermal"))
                    echo "  $zone: ${temp_c}°C"
                fi
            done
        fi
        echo
    fi
}

# 生成测试报告
generate_report() {
    print_message $BLUE "==================== 测试报告 ===================="
    
    echo "测试完成时间: $(date)"
    echo "日志文件位置: $LOG_FILE"
    echo
    
    # 统计测试结果
    passed_tests=$(grep -c "正常\|通过\|健康" "$LOG_FILE")
    failed_tests=$(grep -c "异常\|失败\|错误" "$LOG_FILE")
    
    echo "测试统计:"
    echo "  通过的测试: $passed_tests"
    echo "  失败的测试: $failed_tests"
    echo
    
    if [ $failed_tests -eq 0 ]; then
        print_message $GREEN "所有硬件测试通过！"
    else
        print_message $YELLOW "部分测试存在问题，请检查日志文件"
    fi
    echo
    
    print_message $BLUE "详细测试日志已保存到: $LOG_FILE"
}

# 主函数
main() {
    print_message $GREEN "开始Linux硬件测试..."
    echo "测试开始时间: $(date)"
    echo "=================================================="
    
    # 检查是否为root用户
    if [ "$EUID" -ne 0 ]; then
        print_message $YELLOW "建议使用root权限运行以获得完整的测试结果"
        echo "当前用户: $(whoami)"
        echo
    fi
    
    # 安装必要工具
    install_tools
    
    # 执行各项测试
    system_info
    cpu_test
    memory_test
    disk_test
    network_test
    usb_test
    pci_test
    sensor_test
    
    # 生成报告
    generate_report
    
    print_message $GREEN "硬件测试完成！"
}

# 信号处理
trap 'print_message $RED "测试被中断"; exit 1' INT TERM

# 执行主函数
main "$@"